<template>
  <div class="starfield-container" ref="containerRef">
    <div class="starfield-controls">
      <div class="control-group">
        <label for="magnitudeScale">星等缩放:</label>
        <input 
          id="magnitudeScale" 
          type="range" 
          v-model.number="localMagnitudeScale" 
          min="0.5" 
          max="3.0" 
          step="0.1"
        />
        <span>{{ localMagnitudeScale.toFixed(1) }}</span>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="localShowConstellations" /> 显示星座连线
        </label>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="localShowLabels" /> 显示星座标签
        </label>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="localShowMilkyWay" /> 显示银河
        </label>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="localShowStarNames" /> 显示亮星名称
        </label>
      </div>
      <div class="control-group">
        <label for="twinkleIntensity">闪烁强度:</label>
        <input 
          id="twinkleIntensity" 
          type="range" 
          v-model.number="twinkleIntensity" 
          min="0" 
          max="0.2" 
          step="0.01"
        />
      </div>
      <div class="control-group">
        <label for="rotationSpeed">旋转速度:</label>
        <input 
          id="rotationSpeed" 
          type="range" 
          v-model.number="localRotationSpeed" 
          min="0" 
          max="0.1" 
          step="0.001"
        />
      </div>
    </div>
  </div>
</template>

<script>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import { useThreeScene } from '../composables/useThreeScene'
import * as THREE from 'three'
import { Text } from 'troika-three-text'
import { 
  brightStars, 
  constellationLines, 
  constellations, 
  colorMap,
  filterStarsByMagnitude,
  getConstellationCenter,
  equatorialToCartesian,
  calculateStarSize
} from '../data/hygStarsData'
import { 
  initStarDataWorker, 
  processStarData, 
  processConstellationData, 
  calculateConstellationCenter,
  generateMilkyWayParticles,
  cleanupWorkers
} from '../services/WorkerManager.js'

export default {
  name: 'Starfield',
  props: {
    showConstellations: {
      type: Boolean,
      default: true
    },
    showLabels: {
      type: Boolean,
      default: true
    },
    showMilkyWay: {
      type: Boolean,
      default: true
    },
    showStarNames: {
      type: Boolean,
      default: false
    },
    magnitudeScale: {
      type: Number,
      default: 1.0
    },
    rotationSpeed: {
      type: Number,
      default: 0.01
    },
    maxVisibleMagnitude: {
      type: Number,
      default: 2.5
    }
  },
  setup(props) {
    const containerRef = ref(null)
    let starsGeometry = null
    let starsMaterial = null
    let stars = null
    let animationId = null
    let constellationObjects = []
    let labelObjects = []
    let starNameObjects = []
    let milkyWayObject = null
    let scene = null
    let camera = null
    let renderer = null
    let addObject = null
    let removeObject = null
    
    // 本地状态，用于双向绑定控件
    const localMagnitudeScale = ref(props.magnitudeScale)
    const localShowConstellations = ref(props.showConstellations)
    const localShowLabels = ref(props.showLabels)
    const localShowMilkyWay = ref(props.showMilkyWay)
    const localShowStarNames = ref(props.showStarNames)
    const twinkleIntensity = ref(0.05)
    const localRotationSpeed = ref(props.rotationSpeed)
    
    // 渐进式加载相关状态
    const isLoading = ref(false)
    const loadedStarsCount = ref(0)
    const totalStarsCount = ref(0)
    const currentBatch = ref(0)
    const batchSize = 5000 // 每批加载的星星数量
    const maxBatches = 10 // 最大批次数
    let starsData = [] // 存储所有已加载的星星数据
    
    // 动画相关
    let lastTwinkleUpdate = 0
    const TWINKLE_UPDATE_INTERVAL = 100 // 闪烁更新间隔（毫秒）
    let lastCameraMoveTime = 0
    const CAMERA_MOVE_DELAY = 500 // 相机移动后延迟更新视锥体的时间（毫秒）
    
    // 同步本地状态和props
    watch(() => props.magnitudeScale, (newVal) => {
      localMagnitudeScale.value = newVal
    })
    
    watch(() => props.showConstellations, (newVal) => {
      localShowConstellations.value = newVal
    })
    
    watch(() => props.showLabels, (newVal) => {
      localShowLabels.value = newVal
    })
    
    watch(() => props.showMilkyWay, (newVal) => {
      localShowMilkyWay.value = newVal
    })
    
    watch(() => props.showStarNames, (newVal) => {
      localShowStarNames.value = newVal
    })
    
    watch(() => props.rotationSpeed, (newVal) => {
      localRotationSpeed.value = newVal
    })
    
    // onMounted钩子现在在setup函数末尾，包含了Worker初始化
    
    // 创建基于真实星表的星星 - 使用Web Worker处理
  // 创建基于真实星表的星星 - 支持渐进式加载和视锥体剔除
  const createStars = async () => {
    if (!scene || !camera || !camera.value) return
    
    // 重置加载状态
    isLoading.value = true
    loadedStarsCount.value = 0
    currentBatch.value = 0
    starsData = []
    
    // 移除旧的星星
    if (stars) {
      removeObject(stars)
      starsGeometry.dispose()
      starsMaterial.dispose()
    }
    
    try {
      // 计算视锥体信息
      const frustum = new THREE.Frustum()
      const cameraViewProjectionMatrix = new THREE.Matrix4()
      
      // 更新相机的投影矩阵
      camera.value.updateMatrixWorld()
      cameraViewProjectionMatrix.multiplyMatrices(camera.value.projectionMatrix, camera.value.matrixWorldInverse)
      frustum.setFromProjectionMatrix(cameraViewProjectionMatrix)
      
      // 计算相机距离（简化为到原点的距离）
      const cameraDistance = camera.value.position.length();
      
      // 获取第一批数据（亮星优先）
      const firstBatchResult = await processStarData(brightStars, {
        maxMagnitude: props.maxVisibleMagnitude,
        magnitudeScale: localMagnitudeScale.value,
        distance: 100,
        batchSize: batchSize,
        batchIndex: 0,
        sortByMagnitude: true, // 优先加载亮星
        frustum: {
          planes: frustum.planes.map(p => ({ normal: p.normal.toArray(), constant: p.constant }))
        },
        useLOD: true,
        cameraDistance
      })
      
      totalStarsCount.value = firstBatchResult.totalStars
      starsData.push(...firstBatchResult.stars)
      loadedStarsCount.value = starsData.length
      
      // 创建初始的星星对象
      updateStarsGeometry()
      
      // 继续加载剩余批次
      if (totalStarsCount.value > batchSize) {
        loadNextStarBatches()
      }
      
      isLoading.value = false
    } catch (error) {
      console.error('创建星空失败:', error)
      isLoading.value = false
      // 降级方案：在主线程中处理数据
      createStarsFallback()
    }
  }
  
  // 加载下一批星星数据
  const loadNextStarBatches = async () => {
    if (currentBatch.value >= maxBatches) return
    
    currentBatch.value++
    
    try {
      // 计算当前视锥体
      const frustum = new THREE.Frustum()
      const cameraViewProjectionMatrix = new THREE.Matrix4()
      
      camera.value.updateMatrixWorld()
      cameraViewProjectionMatrix.multiplyMatrices(camera.value.projectionMatrix, camera.value.matrixWorldInverse)
      frustum.setFromProjectionMatrix(cameraViewProjectionMatrix)
      
      // 计算相机距离
      const cameraDistance = camera.value.position.length();
      
      // 获取下一批数据
      const nextBatchResult = await processStarData(brightStars, {
        maxMagnitude: props.maxVisibleMagnitude,
        magnitudeScale: localMagnitudeScale.value,
        distance: 100,
        batchSize: batchSize,
        batchIndex: currentBatch.value,
        sortByMagnitude: true,
        frustum: {
          planes: frustum.planes.map(p => ({ normal: p.normal.toArray(), constant: p.constant }))
        },
        useLOD: true,
        cameraDistance
      })
      
      // 添加新数据
      starsData.push(...nextBatchResult.stars)
      loadedStarsCount.value = starsData.length
      
      // 更新几何体
      updateStarsGeometry()
      
      // 如果还有更多数据，继续加载
      if (loadedStarsCount.value < totalStarsCount.value && currentBatch.value < maxBatches) {
        // 使用setTimeout延迟下一批加载，避免阻塞主线程
        setTimeout(loadNextStarBatches, 100)
      }
    } catch (error) {
      console.error('加载星星批次失败:', error)
    }
  }
  
  // 更新星星几何体
  const updateStarsGeometry = () => {
    const positions = []
    const colors = []
    const sizes = []
    
    // 提取所有星星的数据
    starsData.forEach(star => {
      positions.push(star.x, star.y, star.z)
      colors.push(star.r, star.g, star.b)
      sizes.push(star.size)
    })
    
    // 创建或更新几何体
    if (!starsGeometry) {
      // 从资源池获取几何体
      starsGeometry = resourcePool.get('starGeometry');
      
      // 从资源池获取材质
      starsMaterial = resourcePool.get('starMaterial');
      
      // 创建点对象
      stars = new THREE.Points(starsGeometry, starsMaterial)
      addObject(stars)
    } else {
      // 更新现有的几何体属性
      // 优化：重用缓冲区而不是创建新的
      if (starsGeometry.attributes.position && 
          starsGeometry.attributes.position.count >= positions.length / 3) {
        // 重用现有的缓冲区，只需更新内容
        const positionArray = starsGeometry.attributes.position.array;
        const colorArray = starsGeometry.attributes.color.array;
        const sizeArray = starsGeometry.attributes.size.array;
        
        // 复制新数据到现有数组
        for (let i = 0; i < positions.length; i++) {
          positionArray[i] = positions[i];
        }
        
        for (let i = 0; i < colors.length; i++) {
          colorArray[i] = colors[i];
        }
        
        for (let i = 0; i < sizes.length; i++) {
          sizeArray[i] = sizes[i];
        }
        
        // 标记需要更新
        starsGeometry.attributes.position.needsUpdate = true
        starsGeometry.attributes.color.needsUpdate = true
        starsGeometry.attributes.size.needsUpdate = true
        
        // 如果数据量减少，需要调整绘制范围
        starsGeometry.setDrawRange(0, positions.length / 3);
      } else {
        // 数据量增加，创建新的缓冲区
        starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
        starsGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3))
        starsGeometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1))
      }
    }
  }
  
  // 处理相机移动，更新视锥体
  const handleCameraMove = () => {
    lastCameraMoveTime = performance.now()
    
    // 延迟更新，避免频繁计算
    setTimeout(() => {
      if (performance.now() - lastCameraMoveTime > CAMERA_MOVE_DELAY) {
        updateVisibleStars()
      }
    }, CAMERA_MOVE_DELAY)
  }
  
  // 更新可见的星星（根据视锥体）
  const updateVisibleStars = async () => {
    if (!camera || isLoading.value) return
    
    try {
      // 计算当前视锥体
      const frustum = new THREE.Frustum()
      const cameraViewProjectionMatrix = new THREE.Matrix4()
      
      camera.value.updateMatrixWorld()
      cameraViewProjectionMatrix.multiplyMatrices(camera.value.projectionMatrix, camera.value.matrixWorldInverse)
      frustum.setFromProjectionMatrix(cameraViewProjectionMatrix)
      
      // 计算相机距离
      const cameraDistance = camera.value.position.length();
      
      // 请求Worker更新可见星星
      const result = await processStarData(brightStars, {
        maxMagnitude: props.maxVisibleMagnitude,
        magnitudeScale: localMagnitudeScale.value,
        distance: 100,
        sortByMagnitude: true,
        frustum: {
          planes: frustum.planes.map(p => ({ normal: p.normal.toArray(), constant: p.constant }))
        },
        updateVisibility: true,
        useLOD: true,
        cameraDistance
      })
      
      // 更新数据并重建几何体
      starsData = result.stars
      loadedStarsCount.value = starsData.length
      updateStarsGeometry()
    } catch (error) {
      console.error('更新可见星星失败:', error)
    }
  }
  
  // 降级方案：在主线程中创建星空
  const createStarsFallback = () => {
    // 移除旧的星星
    if (stars) {
      removeObject(stars);
      if (starsGeometry) {
        resourcePool.release('starGeometry', starsGeometry);
        starsGeometry = null;
      }
      if (starsMaterial) {
        resourcePool.release('starMaterial', starsMaterial);
        starsMaterial = null;
      }
      stars = null;
    }
    
    // 根据最大可见星等过滤星星（限制数量以避免阻塞）
    const visibleStars = filterStarsByMagnitude(brightStars, props.maxVisibleMagnitude)
      .slice(0, 2000) // 限制数量
    
    const positions = []
    const colors = []
    const sizes = []
    
    // 为每颗恒星生成位置、颜色和大小
    visibleStars.forEach(star => {
      const pos = equatorialToCartesian(star.ra, star.dec, 100)
      
      positions.push(pos.x, pos.y, pos.z)
      
      // 使用光谱类型对应的颜色
      const spectralType = star.spectral ? star.spectral.charAt(0) : 'Default'
      const color = new THREE.Color(colorMap[spectralType] || colorMap.Default)
      colors.push(color.r, color.g, color.b)
      
      // 根据视星等计算大小
      sizes.push(calculateStarSize(star.mag, localMagnitudeScale.value))
    })
    
    // 从资源池获取几何体和材质
    starsGeometry = resourcePool.get('starGeometry');
    starsGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
    starsGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3))
    starsGeometry.setAttribute('size', new THREE.Float32BufferAttribute(sizes, 1))
    
    starsMaterial = resourcePool.get('starMaterial');
    
    // 创建点对象
    stars = new THREE.Points(starsGeometry, starsMaterial)
    
    // 添加到场景
    addObject(stars)
  }
    
    // 创建亮星名称标签
    const createStarNames = () => {
      if (!scene) return
      
      // 清理旧的名称标签
      starNameObjects.forEach(obj => {
        removeObject(obj)
        obj.dispose()
      })
      starNameObjects = []
      
      // 只为较亮的恒星创建名称标签（星等小于1.5）
      const brightStarsOnly = brightStars.filter(star => star.mag < 1.5 && star.name)
      
      brightStarsOnly.forEach(star => {
        const position = equatorialToCartesian(star.ra, star.dec, 100)
        
        // 创建文本对象
        const text = new Text()
        text.text = star.name
        text.fontSize = 1.5
        
        // 将标签稍微偏移星星位置，避免重叠
        text.position.set(
          position.x + (star.mag < 0 ? 4 : 3),
          position.y + (star.mag < 0 ? 4 : 3),
          position.z
        )
        
        // 使用与星星颜色相似但稍浅的颜色
        const spectralType = star.spectral ? star.spectral.charAt(0) : 'Default'
        const starColor = colorMap[spectralType] || colorMap.Default
        
        // 调整颜色亮度，使其更适合文本
        const colorObj = new THREE.Color(starColor)
        colorObj.multiplyScalar(1.5) // 增加亮度
        text.color = colorObj.getHex()
        
        text.anchorX = 'left'
        text.anchorY = 'middle'
        text.textAlign = 'left'
        
        // 添加轻微的发光效果
        text.outlineWidth = 0.1
        text.outlineColor = 0x222222
        
        // 强制渲染更新
        text.sync()
        
        // 存储引用
        starNameObjects.push(text)
        
        addObject(text)
      })
    }
    
    // 创建星座连线 - 支持视锥体剔除
    const createConstellations = async () => {
      if (!scene || !camera || !camera.value) return
      
      // 清理旧的星座连线
      constellationObjects.forEach(obj => {
        removeObject(obj)
        obj.geometry.dispose()
        obj.material.dispose()
      })
      constellationObjects = []
      
      try {
        // 计算视锥体信息
        const frustum = new THREE.Frustum()
        const cameraViewProjectionMatrix = new THREE.Matrix4()
        
        camera.value.updateMatrixWorld()
        cameraViewProjectionMatrix.multiplyMatrices(camera.value.projectionMatrix, camera.value.matrixWorldInverse)
        frustum.setFromProjectionMatrix(cameraViewProjectionMatrix)
        
        // 使用Web Worker处理星座数据，支持视锥体剔除
        const processedConstellations = await processConstellationData({
          stars: brightStars,
          constellationLines: constellationLines,
          distance: 100,
          frustum: {
            planes: frustum.planes.map(p => ({ normal: p.normal.toArray(), constant: p.constant }))
          }
        })
        
        // 星座颜色映射
        const constellationColors = {
          orion: 0xff6666,     // 红色
          aquila: 0x66ccff,    // 蓝色
          lyra: 0x66ff66,      // 绿色
          canisMajor: 0xffff66,// 黄色
          gemini: 0xff66ff,    // 紫色
          scorpius: 0xff9966,  // 橙色
          vir: 0x9966ff,       // 靛蓝色
          psa: 0x66ffff        // 青色
        }
        
        // 处理每个星座的连线
        processedConstellations.forEach(({ constellationName, lines }) => {
          const color = constellationColors[constellationName] || 0x8888ff
          
          // 从资源池获取材质
          const lineMaterial = resourcePool.get('constellationMaterial');
          lineMaterial.color.set(color); // 设置特定星座的颜色
          
          lines.forEach(linePoints => {
            if (linePoints.length >= 2) {
              const lineGeometry = new THREE.BufferGeometry().setFromPoints(
                linePoints.map(pos => new THREE.Vector3(pos.x, pos.y, pos.z))
              )
              
              const line = new THREE.Line(lineGeometry, lineMaterial)
              addObject(line)
              constellationObjects.push(line)
            }
          })
        })
      } catch (error) {
        console.error('创建星座失败:', error)
        // 降级方案：在主线程中处理数据
        createConstellationsFallback()
      }
    }
    
    // 降级方案：在主线程中创建星座连线
    const createConstellationsFallback = () => {
      // 清理旧的星座连线
      constellationObjects.forEach(obj => {
        removeObject(obj)
        if (obj.geometry) obj.geometry.dispose()
        if (obj.material) {
          resourcePool.release('constellationMaterial', obj.material)
        }
      })
      constellationObjects = []
      
      // 星座颜色映射
      const constellationColors = {
        orion: 0xff6666,     // 红色
        aquila: 0x66ccff,    // 蓝色
        lyra: 0x66ff66,      // 绿色
        canisMajor: 0xffff66,// 黄色
        gemini: 0xff66ff,    // 紫色
        scorpius: 0xff9966,  // 橙色
        vir: 0x9966ff,       // 靛蓝色
        psa: 0x66ffff        // 青色
      }
      
      // 简化处理：只创建主要星座
      const mainConstellations = ['orion', 'aquila', 'lyra', 'canisMajor']
      
      mainConstellations.forEach(constellationName => {
        if (constellationLines[constellationName]) {
          const color = constellationColors[constellationName] || 0x8888ff
          
          const lineMaterial = new THREE.LineBasicMaterial({
            color: color,
            transparent: true,
            opacity: 0.8,
            linewidth: 1.5
          })
          
          constellationLines[constellationName].forEach(pair => {
            const star1 = brightStars.find(s => s.id === pair[0])
            const star2 = brightStars.find(s => s.id === pair[1])
            
            if (star1 && star2) {
              // 使用简化的坐标转换
              const pos1 = {
                x: star1.ra * Math.cos(star1.dec * Math.PI / 180),
                y: star1.dec,
                z: star1.ra * Math.sin(star1.dec * Math.PI / 180)
              }
              const pos2 = {
                x: star2.ra * Math.cos(star2.dec * Math.PI / 180),
                y: star2.dec,
                z: star2.ra * Math.sin(star2.dec * Math.PI / 180)
              }
              
              const lineGeometry = new THREE.BufferGeometry().setFromPoints([
                new THREE.Vector3(pos1.x, pos1.y, pos1.z),
                new THREE.Vector3(pos2.x, pos2.y, pos2.z)
              ])
              
              const line = new THREE.Line(lineGeometry, lineMaterial)
              addObject(line)
              constellationObjects.push(line)
            }
          })
        }
      })
    }
    
    // 创建星座标签 - 增强版，支持缩写
    const createConstellationLabels = () => {
      if (!scene) return
      
      // 清理旧的标签
      labelObjects.forEach(obj => {
        removeObject(obj)
        obj.dispose()
      })
      labelObjects = []
      
      constellations.forEach(constellation => {
        // 使用更准确的星座中心点计算
        const center = getConstellationCenter(constellation.name, 100)
        
        const text = new Text()
        // 显示星座名称和缩写
        text.text = constellation.abbreviation 
          ? `${constellation.name} (${constellation.abbreviation})` 
          : constellation.name
        
        text.fontSize = 2.0
        text.position.set(center.x, center.y, center.z)
        text.color = 0xaaaaaa
        text.anchorX = 'center'
        text.anchorY = 'middle'
        text.textAlign = 'center'
        
        // 添加发光效果使标签在黑暗背景中更明显
        text.outlineWidth = 0.1
        text.outlineColor = 0x444444
        
        text.sync() // 确保文本几何体被创建
        
        addObject(text)
        labelObjects.push(text)
      })
    }
    
    // 添加银河效果 - 使用Web Worker生成粒子数据
  const addMilkyWay = async () => {
    if (!scene || !camera || !camera.value) return
    
    // 如果已经有银河对象，先移除
    if (milkyWayObject) {
      removeObject(milkyWayObject)
      if (milkyWayObject.material.map) {
        milkyWayObject.material.map.dispose()
      }
      milkyWayObject.geometry.dispose()
      milkyWayObject.material.dispose()
      
      // 移除粒子系统
      if (milkyWayObject.particleSystem) {
        removeObject(milkyWayObject.particleSystem)
        milkyWayObject.particleSystem.geometry.dispose()
        milkyWayObject.particleSystem.material.dispose()
      }
    }
    
    // 创建银河平面
    const milkyWayGeometry = new THREE.PlaneGeometry(2000, 1000, 1, 1)
    
    // 生成改进的渐变纹理
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = 1024
    canvas.height = 512
    
    // 创建径向渐变
    const gradient = ctx.createRadialGradient(
      canvas.width / 2,
      canvas.height / 2,
      0,
      canvas.width / 2,
      canvas.height / 2,
      canvas.width * 0.7
    )
    
    // 使用更真实的银河颜色
    gradient.addColorStop(0, 'rgba(200, 180, 255, 0.4)')
    gradient.addColorStop(0.2, 'rgba(120, 80, 200, 0.3)')
    gradient.addColorStop(0.5, 'rgba(60, 30, 120, 0.2)')
    gradient.addColorStop(1, 'rgba(0, 0, 0, 0)')
    
    ctx.fillStyle = gradient
    ctx.fillRect(0, 0, canvas.width, canvas.height)
    
    // 添加一些不规则的结构
    ctx.fillStyle = 'rgba(200, 180, 255, 0.2)'
    for (let i = 0; i < 50; i++) {
      const x = canvas.width / 2 + (Math.random() - 0.5) * canvas.width * 0.8
      const y = canvas.height / 2 + (Math.random() - 0.5) * canvas.height * 0.8
      const size = 5 + Math.random() * 20
      
      ctx.beginPath()
      ctx.arc(x, y, size, 0, Math.PI * 2)
      ctx.fill()
    }
    
    // 创建纹理
    const texture = new THREE.CanvasTexture(canvas)
    texture.wrapS = THREE.ClampToEdgeWrapping
    texture.wrapT = THREE.ClampToEdgeWrapping
    
    // 创建材质
    const milkyWayMaterial = new THREE.MeshBasicMaterial({
      map: texture,
      transparent: true,
      blending: THREE.AdditiveBlending,
      side: THREE.DoubleSide
    })
    
    // 创建银河网格
    milkyWayObject = new THREE.Mesh(milkyWayGeometry, milkyWayMaterial)
    milkyWayObject.position.set(0, 0, -500)
    milkyWayObject.rotation.x = Math.PI / 2
    
    // 添加到场景
    addObject(milkyWayObject)
    
    try {
      // 计算视锥体信息
      const frustum = new THREE.Frustum()
      const cameraViewProjectionMatrix = new THREE.Matrix4()
      
      camera.value.updateMatrixWorld()
      cameraViewProjectionMatrix.multiplyMatrices(camera.value.projectionMatrix, camera.value.matrixWorldInverse)
      frustum.setFromProjectionMatrix(cameraViewProjectionMatrix)
      
      // 使用Web Worker生成银河粒子数据，支持分批加载和视锥体剔除
      const result = await generateMilkyWayParticles(2000, {
        radius: 500,
        height: 100,
        densityPower: 1.5,
        batchSize: 500,
        batchIndex: 0,
        frustum: {
          planes: frustum.planes.map(p => ({ normal: p.normal.toArray(), constant: p.constant }))
        }
      })
      
      // 使用返回的positions数组
      const positions = result.positions
      
      // 创建粒子系统模拟银河中的恒星密度
      const particleGeometry = new THREE.BufferGeometry()
      particleGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
      
      const particleMaterial = new THREE.PointsMaterial({
        color: 0xffffff,
        size: 0.5,
        transparent: true,
        opacity: 0.8
      })
      
      const particleSystem = new THREE.Points(particleGeometry, particleMaterial)
      particleSystem.rotation.x = Math.PI / 2
      
      addObject(particleSystem)
      
      // 存储粒子系统引用
      milkyWayObject.particleSystem = particleSystem
    } catch (error) {
      console.error('创建银河粒子系统失败:', error)
      // 降级方案：在主线程中创建粒子系统
      createMilkyWayParticlesFallback()
    }
  }
  
  // 降级方案：在主线程中创建银河粒子系统
  const createMilkyWayParticlesFallback = () => {
    // 创建粒子系统模拟银河中的恒星密度
    const particleGeometry = new THREE.BufferGeometry()
    const particleCount = 1000 // 减少粒子数量以避免阻塞主线程
    const positions = new Float32Array(particleCount * 3)
    
    for (let i = 0; i < particleCount; i++) {
      // 在银河平面上随机分布，但更集中在中心区域
      const angle = Math.random() * Math.PI * 2
      const radius = Math.pow(Math.random(), 1.5) * 400 // 使用幂函数使分布更集中
      
      positions[i * 3] = Math.cos(angle) * radius
      positions[i * 3 + 1] = Math.sin(angle) * radius
      positions[i * 3 + 2] = -499.9 // 略高于银河平面
    }
    
    particleGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
    
    const particleMaterial = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 0.5,
      transparent: true,
      opacity: 0.7
    })
    
    const particleSystem = new THREE.Points(particleGeometry, particleMaterial)
    particleSystem.rotation.x = Math.PI / 2
    
    addObject(particleSystem)
    
    // 存储粒子系统引用
    milkyWayObject.particleSystem = particleSystem
  }
    
    // 应用星星闪烁效果
    const applyTwinkleEffect = () => {
      const now = performance.now()
      
      // 控制闪烁更新频率
      if (now - lastTwinkleUpdate > TWINKLE_UPDATE_INTERVAL) {
        if (stars && starsMaterial) {
          // 调整整体透明度来模拟闪烁效果
          const twinkleFactor = calculateTwinkleFactor(twinkleIntensity.value)
          starsMaterial.opacity = Math.min(1.0, 0.8 + twinkleFactor * 0.2)
          starsMaterial.emissiveIntensity = 0.1 + twinkleFactor * 0.1
        }
        
        lastTwinkleUpdate = now
      }
    }
    
    // 动画循环 - 增强版，支持星星闪烁和相机移动检测
    const animate = () => {
      animationId = requestAnimationFrame(animate)
      
      // 缓慢旋转场景
      if (stars) {
        stars.rotation.y += localRotationSpeed.value * 0.1
        
        // 检测相机移动（旋转也算移动）
        handleCameraMove()
      }
      
      // 应用星星闪烁效果
      applyTwinkleEffect()
    }
    

    
    // 资源池管理类
    class ResourcePool {
      constructor() {
        this.pools = new Map();
      }
      
      // 创建或获取资源
      get(type, createFn, disposeFn) {
        if (!this.pools.has(type)) {
          this.pools.set(type, { items: [], createFn, disposeFn });
        }
        
        const pool = this.pools.get(type);
        
        if (pool.items.length > 0) {
          return pool.items.pop();
        }
        
        return createFn();
      }
      
      // 回收资源
      release(type, resource) {
        if (this.pools.has(type) && resource) {
          this.pools.get(type).items.push(resource);
        }
      }
      
      // 清理指定类型的资源池
      clear(type) {
        if (this.pools.has(type)) {
          const pool = this.pools.get(type);
          pool.items.forEach(item => {
            if (item) pool.disposeFn(item);
          });
          pool.items = [];
        }
      }
      
      // 清理所有资源池
      clearAll() {
        this.pools.forEach((pool, type) => this.clear(type));
        this.pools.clear();
      }
    }
    
    // 创建资源池实例
    const resourcePool = new ResourcePool();
    
    // 定义资源池类型和处理函数
    const registerResourceTypes = () => {
      // 星星几何体池
      resourcePool.get('starGeometry', 
        () => new THREE.BufferGeometry(), 
        (geo) => geo.dispose()
      );
      
      // 星星材质池
      resourcePool.get('starMaterial', 
        () => new THREE.PointsMaterial({
          size: 1,
          vertexColors: true,
          sizeAttenuation: true,
          transparent: true,
          opacity: 1.0,
          blending: THREE.AdditiveBlending,
          emissive: 0xffffff,
          emissiveIntensity: 0.1
        }), 
        (mat) => mat.dispose()
      );
      
      // 星座线材质池
      resourcePool.get('constellationMaterial', 
        () => new THREE.LineBasicMaterial({
          color: 0xaaaaaa,
          transparent: true,
          opacity: 0.8,
          linewidth: 1.5
        }), 
        (mat) => mat.dispose()
      );
    };
    
    // 初始化资源池
    registerResourceTypes();
    
    // 优化的清理资源函数
    const cleanup = () => {
      // 停止动画循环
      if (animationId) {
        cancelAnimationFrame(animationId);
        animationId = null;
      }
      
      // 清理星星对象
      if (stars) {
        removeObject(stars);
        stars = null;
      }
      if (starsGeometry) {
        resourcePool.release('starGeometry', starsGeometry);
        starsGeometry = null;
      }
      if (starsMaterial) {
        resourcePool.release('starMaterial', starsMaterial);
        starsMaterial = null;
      }
      
      // 清理星座对象
      constellationObjects.forEach(obj => {
        removeObject(obj);
        if (obj.geometry) obj.geometry.dispose();
        if (obj.material) {
          resourcePool.release('constellationMaterial', obj.material);
        }
      });
      constellationObjects = [];
      
      // 清理标签对象
      if (labelObjects && labelObjects.length > 0) {
        labelObjects.forEach(obj => {
          if (obj) {
            removeObject(obj);
            if (typeof obj.dispose === 'function') {
              obj.dispose();
            }
          }
        });
        labelObjects = [];
      }
      
      if (starNameObjects && starNameObjects.length > 0) {
        starNameObjects.forEach(obj => {
          if (obj) {
            removeObject(obj);
            if (typeof obj.dispose === 'function') {
              obj.dispose();
            }
          }
        });
        starNameObjects = [];
      }
      
      // 清理银河对象
      if (milkyWayObject) {
        removeObject(milkyWayObject);
        if (milkyWayObject.material) {
          if (milkyWayObject.material.map) {
            milkyWayObject.material.map.dispose();
          }
          milkyWayObject.material.dispose();
        }
        if (milkyWayObject.geometry) {
          milkyWayObject.geometry.dispose();
        }
        
        if (milkyWayObject.particleSystem) {
          removeObject(milkyWayObject.particleSystem);
          if (milkyWayObject.particleSystem.material) {
            milkyWayObject.particleSystem.material.dispose();
          }
          if (milkyWayObject.particleSystem.geometry) {
            milkyWayObject.particleSystem.geometry.dispose();
          }
        }
        milkyWayObject = null;
      }
      
      // 清理场景和渲染器 (如果需要)
      if (renderer) {
        // 注意：这里不应该dispose renderer，因为它可能被其他组件使用
        // 只在组件完全卸载时清理
      }
    };
    
    // 深度清理函数 - 在组件完全卸载时调用
    const deepCleanup = () => {
      // 先执行常规清理
      cleanup();
      
      // 清理资源池中的所有资源
      resourcePool.clearAll();
      
      // 清理渲染器和场景 (如果拥有所有权)
      if (renderer) {
        // 如果我们拥有渲染器的所有权，可以在这里dispose
        // 但在这个组件中，渲染器是通过useThreeScene提供的，不应该在这里dispose
      }
      
      // 清空引用
      scene = null;
      camera = null;
      renderer = null;
      addObject = null;
      removeObject = null;
      
      // 清空数据数组
      starsData = [];
    };
    
    onUnmounted(() => {
      cleanup()
    })
    
    // 监听本地状态变化，实现实时控制
    watch(localMagnitudeScale, () => {
      createStars()
    })
    
    watch(localShowConstellations, (show) => {
      if (show) {
        createConstellations()
      } else {
        constellationObjects.forEach(obj => {
          removeObject(obj)
          obj.geometry.dispose()
          obj.material.dispose()
        })
        constellationObjects = []
      }
    })
    
    watch(localShowLabels, (show) => {
      if (show) {
        createConstellationLabels()
      } else {
        labelObjects.forEach(obj => {
          removeObject(obj)
          obj.dispose()
        })
        labelObjects = []
      }
    })
    
    watch(localShowMilkyWay, (show) => {
      if (show) {
        addMilkyWay()
      } else if (milkyWayObject) {
        removeObject(milkyWayObject)
        if (milkyWayObject.particleSystem) {
          removeObject(milkyWayObject.particleSystem)
        }
        milkyWayObject = null
      }
    })
    
    watch(localShowStarNames, (show) => {
      if (show) {
        createStarNames()
      } else {
        starNameObjects.forEach(obj => {
          removeObject(obj)
          obj.dispose()
        })
        starNameObjects = []
      }
    })
    
    // 在组件挂载时初始化Worker
    onMounted(() => {
      if (containerRef.value) {
        // 使用Three.js场景组合式函数
        const sceneData = useThreeScene({
          container: containerRef.value,
          cameraConfig: {
              fov: 75,
              near: 1,
              far: 10000,
              position: { x: 0, y: 0, z: 100 }
            }
        })
        
        scene = sceneData.scene
        camera = sceneData.camera
        renderer = sceneData.renderer
        addObject = sceneData.addObject
        removeObject = sceneData.removeObject
        
        // 初始化Worker
        initStarDataWorker().catch(error => {
          console.error('初始化星数据Worker失败:', error)
        })
        
        // 初始化星星、星座等
        createStars()
        if (localShowConstellations.value) {
          createConstellations()
        }
        if (localShowLabels.value) {
          createConstellationLabels()
        }
        if (localShowMilkyWay.value) {
          addMilkyWay()
        }
        if (localShowStarNames.value) {
          createStarNames()
        }
        animate()
      }
    })
    
    // 清理Workers
    onUnmounted(() => {
      deepCleanup()
      cleanupWorkers().catch(error => {
        console.error('清理Workers失败:', error)
      })
    })
    
    return {
      containerRef,
      localMagnitudeScale,
      localShowConstellations,
      localShowLabels,
      localShowMilkyWay,
      localShowStarNames,
      twinkleIntensity,
      localRotationSpeed,
      isLoading,
      loadedStarsCount,
      totalStarsCount
    }
  }
}
</script>

<style scoped>
.starfield-container {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
  overflow: hidden;
}

.starfield-controls {
  position: absolute;
  top: 20px;
  left: 20px;
  background-color: rgba(0, 0, 0, 0.7);
  padding: 15px;
  border-radius: 8px;
  backdrop-filter: blur(10px);
  z-index: 10;
  color: #fff;
  font-family: Arial, sans-serif;
  font-size: 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.control-group {
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.control-group:last-child {
  margin-bottom: 0;
}

.control-group label {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}

.control-group input[type="range"] {
  width: 100px;
  cursor: pointer;
}

.control-group input[type="checkbox"] {
  cursor: pointer;
  width: 16px;
  height: 16px;
}

.control-group span {
  min-width: 35px;
  text-align: center;
  color: #aaa;
  font-size: 12px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .starfield-controls {
    top: 10px;
    left: 10px;
    right: 10px;
    padding: 10px;
    font-size: 12px;
  }
  
  .control-group {
    margin-bottom: 8px;
  }
  
  .control-group input[type="range"] {
    width: 80px;
  }
}
</style>